package main

import (
	"fmt"
	"reflect"
)

type Person struct {
	name string
	age  int
}

func (p Person) SayBye() string {
	return "Bye"
}

func (p Person) SayHello() string {
	return "Hello"
}

func (person Person) printInfo(gender string, hobby string) {
	fmt.Printf("name: %s    age: %d    gender: %s    hobby: %s", person.name, person.age, gender, hobby)
}

func main() {
	person := &Person{name: "堂吉诃德·多弗朗明哥", age: 27}
	// gender := "male"

	t := reflect.TypeOf(person)
	v := reflect.ValueOf(person)

	// 动态调用函数（使用索引且无参数）
	for i := 0; i < v.NumMethod(); i++ {
		fmt.Printf("调用第 %d 个方法：%v， 调用结果：%v\n", i+1, t.Method(i).Name, v.Elem().Method(i).Call(nil))
	}

	// 动态调用函数（使用函数名且无参数）
	fmt.Println(v.MethodByName("SayHello").Call(nil))
	fmt.Println(v.MethodByName("SayBye").Call(nil))

	// 动态调用函数（使用函数且有参数）
	gender := reflect.ValueOf("male")
	hobby := reflect.ValueOf("bicycle")
	input := []reflect.Value{gender, hobby}
	v.MethodByName("printInfo").Call(input)
}
